﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace QL_Truong_Hoc
{
    struct svien
    {
        public float diemtb;
        public int doituong;
        public int vung;
    }


    public partial class frmPhanCum : DevExpress.XtraEditors.XtraForm
    {

        public frmPhanCum()
        {
            InitializeComponent();
        }

      
        svien[] nhom;
        svien[] tamcum;
        float[] pi;
        float[,] xij;
        int sopt;
        float ra = 0.25f;
        int socum;
        float etren = 0.5f;
        float eduoi = 0.2f;
        float beta = 1.5f;

        float distance(svien xi, svien xj)
        {
            float t1 = xi.diemtb - xj.diemtb;
            float reval = t1*t1;
            t1 = xi.doituong - xj.doituong;
            reval += t1 * t1;
            t1 = xi.vung - xj.vung;
            reval += t1 * t1;

            return reval;
        }

        DataTable DataObjPhancum;
        private void frmPhanCum_Load(object sender, EventArgs e)
        {
            string sqlData = "Select id,hoten,doituong,diemxlTN,noisinh,xeploaiTN from tXeploai";
            DataObjPhancum = Extend.SqlString.libSqlString.ThucThiCauTruyVan_TraVeBang(sqlData);
            DataLoad.DataSource = DataObjPhancum;
        }

        private void btPhantich_Click(object sender, EventArgs e)
        {
            MessageBox.Show(sopt.ToString());
            try
            {

                //sopt = 10;//so sv trong csdl
                sopt = DataObjPhancum.Rows.Count;
                MessageBox.Show(sopt.ToString());
                ra = 0.25f;
                etren = 0.5f;
                eduoi = 0.2f;
                beta = 1.5f;

                tamcum = new svien[100];
                nhom = new svien[sopt];

                pi = new float[sopt];
                xij = new float[sopt, sopt];


                float rainv = -4.0f / ra;
                int idmax = 0;
                float pimax = 0;
                //doc du lieu sv vao mang
                for (int i = 0; i < sopt; i++)
                {
                    svien sv = new svien();
                    int ObjDtuong = 0;
                    if (Convert.ToBoolean(DataObjPhancum.Rows[i]["doituong"]))
                        ObjDtuong = 1;
                    sv.diemtb = float.Parse(DataObjPhancum.Rows[i]["diemxlTN"].ToString());
                    sv.vung = int.Parse(DataObjPhancum.Rows[i]["noisinh"].ToString());
                    sv.doituong = ObjDtuong;
                    nhom[i] = sv;
                }

                MessageBox.Show("1111111");

                for (int i = 0; i < sopt; i++)
                {
                    for (int j = i; j < sopt; j++)
                    {
                        xij[i, j] = distance(nhom[i], nhom[j]);
                    }
                }

                MessageBox.Show("222222222");

                for (int i = 0; i < sopt; i++)
                {
                    pi[i] = 0;
                    for (int j = 0; j < sopt; j++)
                    {
                        if (i < j)
                            pi[i] += (float)Math.Exp(rainv * xij[i, j]);
                        else
                            pi[i] += (float)Math.Exp(rainv * xij[j, i]);
                    }
                    if (pimax < pi[i])
                    {
                        pimax = pi[i];
                        idmax = i;
                    }
                }
                socum = 1;
                tamcum[0] = nhom[idmax];

                float dmin = 0;
                float dk = 0;

                // LỖI TRONG VÒNG LẶP
                while (true)
                {
                    float pkmax = pimax;
                    int idkmax = idmax;
                    float pmax = 0;
                    int imax = 0;
                    for (int i = 0; i < sopt; i++)
                    {
                        if (i < idkmax)
                            pi[i] -= pkmax * (float)Math.Exp(-beta * xij[i, idkmax]);
                        else
                            pi[i] -= pkmax * (float)Math.Exp(-beta * xij[idkmax, i]);

                        if (pmax < pi[i])
                        {
                            pmax = pi[i];
                            imax = i;
                        }


                        if (pkmax > etren * pmax)
                        {//chon imax la tam cun tiep theo
                            socum++;
                            tamcum[socum - 1] = nhom[imax];

                            pkmax = pmax;
                            idmax = imax;
                        }

                        else
                        {
                            if (pkmax < eduoi * pmax) //dung thuat toan
                                break;
                            else
                            {
                                //tinh Dmin
                                dmin = 9999999.0f;
                                for (int k = 0; k < socum; k++)
                                {
                                    dk = distance(nhom[imax], tamcum[k]);
                                    if (dk < dmin) dmin = dk;
                                }

                                // dieu kien dung
                                if (dmin / ra + pkmax / pmax >= 1.0)
                                {
                                    socum++;
                                    tamcum[socum - 1] = nhom[imax];

                                    pkmax = pmax;
                                    idmax = imax;
                                }
                                else
                                {
                                    pkmax = 0;
                                }
                            }
                        }
                    }

                    MessageBox.Show(imax.ToString());
                }

                //in ra cac tam cum
                for (int f = 0; f < socum; f++)
                {
                    //in tamcum[i].
                }
            }
            catch (Exception ex) { MessageBox.Show(ex.Message); }
        }

        private void button1_Click(object sender, EventArgs e)
        {
            int i = 0;
        }


    }
}
